package com.cyzy.homework.repository;

import com.cyzy.homework.entity.Message;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.util.List;
import java.util.Optional;

/**
 * 消息数据访问层
 */
@Repository
public interface MessageRepository extends JpaRepository<Message, Long> {
    
    /**
     * 根据消息ID查找消息
     */
    Optional<Message> findByMessageId(String messageId);
    
    /**
     * 根据接收者ID查询消息列表（分页）
     */
    Page<Message> findByToUserIdAndStatusOrderBySendTimeDesc(String toUserId, Integer status, Pageable pageable);
    
    /**
     * 根据接收者ID和消息类型查询消息列表
     */
    Page<Message> findByToUserIdAndTypeAndStatusOrderBySendTimeDesc(String toUserId, String type, Integer status, Pageable pageable);
    
    /**
     * 根据接收者ID和是否已读状态查询消息列表
     */
    Page<Message> findByToUserIdAndIsReadAndStatusOrderBySendTimeDesc(String toUserId, Integer isRead, Integer status, Pageable pageable);
    
    /**
     * 查询用户未读消息数量
     */
    long countByToUserIdAndIsReadAndStatus(String toUserId, Integer isRead, Integer status);
    
    /**
     * 根据类型统计用户未读消息数量
     */
    long countByToUserIdAndTypeAndIsReadAndStatus(String toUserId, String type, Integer isRead, Integer status);
    
    /**
     * 查询用户最近的消息
     */
    @Query("SELECT m FROM Message m WHERE m.toUserId = :toUserId AND m.status = 0 " +
           "ORDER BY m.sendTime DESC")
    List<Message> findRecentMessages(@Param("toUserId") String toUserId, Pageable pageable);
    
    /**
     * 批量标记消息为已读
     */
    @Modifying
    @Query("UPDATE Message m SET m.isRead = 1, m.readTime = :readTime, m.updateTime = :updateTime " +
           "WHERE m.toUserId = :toUserId AND m.isRead = 0 AND m.status = 0")
    int markAllAsRead(@Param("toUserId") String toUserId, 
                     @Param("readTime") Timestamp readTime, 
                     @Param("updateTime") Timestamp updateTime);
    
    /**
     * 标记单个消息为已读
     */
    @Modifying
    @Query("UPDATE Message m SET m.isRead = 1, m.readTime = :readTime, m.updateTime = :updateTime " +
           "WHERE m.messageId = :messageId AND m.toUserId = :toUserId")
    int markAsRead(@Param("messageId") String messageId, 
                  @Param("toUserId") String toUserId,
                  @Param("readTime") Timestamp readTime,
                  @Param("updateTime") Timestamp updateTime);
    
    /**
     * 软删除消息
     */
    @Modifying
    @Query("UPDATE Message m SET m.status = 1, m.updateTime = :updateTime " +
           "WHERE m.messageId = :messageId AND m.toUserId = :toUserId")
    int deleteMessage(@Param("messageId") String messageId,
                     @Param("toUserId") String toUserId,
                     @Param("updateTime") Timestamp updateTime);
    
    /**
     * 根据时间范围查询消息
     */
    @Query("SELECT m FROM Message m WHERE m.toUserId = :toUserId AND m.status = 0 " +
           "AND m.sendTime BETWEEN :startTime AND :endTime " +
           "ORDER BY m.sendTime DESC")
    List<Message> findMessagesByTimeRange(@Param("toUserId") String toUserId,
                                        @Param("startTime") Timestamp startTime,
                                        @Param("endTime") Timestamp endTime);
    
    /**
     * 清理过期消息（物理删除）
     */
    @Modifying
    @Query("DELETE FROM Message m WHERE m.status = 1 AND m.updateTime < :expireTime")
    int cleanupExpiredMessages(@Param("expireTime") Timestamp expireTime);
}





















